package org.aeon.server.handler.Inbound;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.aeon.entity.FriendApply;
import org.aeon.entity.User;
import org.aeon.entity.UserRelation;
import org.aeon.entity.dto.FriendApplyDto;
import org.aeon.entity.dto.UserDto;
import org.aeon.message.request.FriendApplyRequestMessage;
import org.aeon.message.response.FriendApplyResponseMessage;
import org.aeon.service.FriendApplyService;
import org.aeon.service.Session;
import org.aeon.service.UserRelationService;
import org.aeon.service.factory.FriendApplyServiceFactory;
import org.aeon.service.factory.SessionFactory;
import org.aeon.service.factory.UserRelationServiceFactory;
import org.aeon.service.factory.UserServiceFactory;
import org.modelmapper.ModelMapper;

import java.util.Date;

/**
 * @author: MissingAeon
 * @date: 2024/1/29 10:23
 * @description: 好友申请请求消息处理程序
 */
@Slf4j
@ChannelHandler.Sharable
public class FriendApplyRequestHandler extends SimpleChannelInboundHandler<FriendApplyRequestMessage> {
    private static boolean blacklistCheck(UserRelationService relationService, Long to, Long form) {
        final UserRelation relation = relationService.queryRelation(to, form);
        return relation != null && !relation.getIsFriend();
    }

    private static boolean friendCheck(UserRelationService relationService, Long form, Long to) {
        return relationService.queryRelation(form, to) != null;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FriendApplyRequestMessage msg) throws Exception {
        final FriendApplyResponseMessage resMsg = new FriendApplyResponseMessage();
        resMsg.setResponseID(msg.getUid());

        final FriendApplyDto friendApply = msg.getFriendApply();
        final Long form = friendApply.getUserId();
        final Long to = friendApply.getAnotherUserId();
        final UserRelationService relationService = UserRelationServiceFactory.getService();
        final FriendApplyService applyService = FriendApplyServiceFactory.getService();

        if (form.equals(to)) {
            // 目标检查
            resMsg.setResponse(false, "不可以加自己为好友");
            ctx.writeAndFlush(resMsg);
            return;
        } else if (!UserServiceFactory.getService().isUserExist(to)) {
            // 不存在，失败
            resMsg.setResponse(false, "该用户不存在");
        } else if (friendCheck(relationService, form, to)) {
            // 原有关系检查
            resMsg.setResponse(false, "已是好友关系");
        } else if (blacklistCheck(relationService, to, form)) {
            // 黑名单检查
            resMsg.setResponse(false, "您已被对方加入黑名单");
        } else if (applyService.isApplyExist(form, to)) {
            // 重复申请检查
            resMsg.setResponse(false, "重复的好友请求");
        } else {
            // 成功
            resMsg.setResponse(true, "申请已发送");
            // 保存
            friendApply.setCreateTime(new Date());
            applyService.addFriendApply(new ModelMapper().map(friendApply, FriendApply.class));

            // 向目标发送
            final Session session = SessionFactory.getSession();
            final Channel channel = session.getChannel(to);
            if (channel != null) {
                final User user = UserServiceFactory.getService().getUserById(form);
                final FriendApplyResponseMessage deriveMessage = new FriendApplyResponseMessage();
                deriveMessage.setResponse(true, "收到好友信息");
                // 只发送请求用户信息
                deriveMessage.setMessage(new ModelMapper().map(user, UserDto.class));
                channel.writeAndFlush(deriveMessage);
            }
        }
        // 回应
        ctx.writeAndFlush(resMsg);
    }
}
